package mredis

import (
	"fmt"
	"time"
	"errors"
)

// 删除一个key
func (c *Command) Del(key string) (int64,error)  {
	if c.conn == nil {
		return -1,RedisConnError
	}
	_,err := c.conn.WriteString(fmt.Sprintf("DEL %s\r\n",key))
	if err != nil {
		return 0,err
	}
	return c.conn.ReadAsInt()
}

// 执行 DUMP 命令
func(c *Command) Dump(key string) (string,error){
	if c.conn == nil {
		return "",RedisConnError
	}
	_,err := c.conn.WriteString(fmt.Sprintf("DUMP %s\r\n",key))
	if err != nil {
		return "",err
	}

	b,err := c.conn.ReadAsString()
	if err != nil {
		return "",err
	}
	return string(b),nil
}
// 判断一个key是否存在
func (c *Command) Exists(key string) (bool,error) {
	if c.conn == nil {
		return false,RedisConnError
	}

	_,err := c.conn.WriteString(fmt.Sprintf("EXISTS %s\r\n",key))
	if err != nil {
		return false,err
	}
	i,err := c.conn.ReadAsInt()
	return i==1,nil
}
// 设置一个key的过期时间
func (c *Command) Expire(key string,s time.Duration) (bool,error) {
	if c.conn == nil {
		return false,RedisConnError
	}
	_,err := c.conn.WriteString(fmt.Sprintf("EXPIRE %s %d\r\n",key,int(s.Seconds())))
	if err != nil {
		return false,err
	}
	i,err := c.conn.ReadAsInt()
	return i==1,nil
}
//以 UNIX 时间戳(unix timestamp)格式设置 key 的过期时间
func (c *Command) ExpireAt(key string,t time.Time)(bool,error) {
	if c.conn == nil {
		return false,RedisConnError
	}

	_,err := c.conn.WriteString(fmt.Sprintf("EXPIREAT %s %d\r\n",key,t.Unix()))
	if err != nil {
		return false,err
	}
	i,err := c.conn.ReadAsInt()
	return i==1,nil
}
//设置 key 的过期时间，已毫秒计的时间戳
func (c *Command) PexpireAt(key string,t time.Time)(bool,error) {
	if c.conn == nil {
		return false,RedisConnError
	}

	n := int(t.UnixNano()/1000000)
	_,err := c.conn.WriteString(fmt.Sprintf("PEXPIREAT %s %d\r\n",key,n))
	if err != nil {
		return false,err
	}
	i,err := c.conn.ReadAsInt()
	return i==1,nil
}
//获取key列表
func (c *Command) Keys(key string) ([]string,error) {
	if c.conn == nil {
		return nil,RedisConnError
	}
	_,err := c.conn.WriteString(fmt.Sprintf("KEYS %s\r\n",key))
	if err != nil {
		return nil,err
	}

	b,err := c.conn.ReadAsArray()
	return b,err
}
//将当前数据库的 key 移动到给定的数据库 db 当中。
func (c *Command) Move(key string,db int)(error){
	if c.conn == nil {
		return RedisConnError
	}

	_,err := c.conn.WriteString(fmt.Sprintf("MOVE %s %d\r\n",key,db))
	if err != nil {
		return err
	}
	i,err := c.conn.ReadAsInt();
	if err != nil {
		return err
	}
	if i == 0 {
		return RedisError("Move failed")
	}
	return nil
}
//移除给定 key 的过期时间，使得 key 永不过期。
func (c *Command) Persist(key string)(error){
	if c.conn == nil {
		return RedisConnError
	}

	_,err := c.conn.WriteString(fmt.Sprintf("PERSIST %s\r\n",key))
	if err != nil {
		return err
	}
	i,err := c.conn.ReadAsInt();
	if err != nil {
		return err
	}
	if i == 0 {
		return RedisError("Persist failed")
	}
	return nil
}
//Redis Pttl 命令以毫秒为单位返回 key 的剩余过期时间。如果key设置的过期时间不是毫秒，则会返回空
func (c *Command) Pttl(key string) (int64,error){
	if c.conn == nil {
		return 0,RedisConnError
	}

	_,err := c.conn.WriteString(fmt.Sprintf("PTTL %s\r\n",key))
	if err != nil {
		return 0,err
	}
	i,err := c.conn.ReadAsInt()
	if err != nil {
		return 0,err
	}
	if i == -2{
		return 0,RedisKeyNotExist
	}
	return i,nil
}


//Redis TTL 命令以秒为单位返回 key 的剩余过期时间。
func (c *Command) Ttl(key string) (int64,error){
	if c.conn == nil {
		return 0,RedisConnError
	}

	_,err := c.conn.WriteString(fmt.Sprintf("TTL %s\r\n",key))
	if err != nil {
		return 0,err
	}
	i,err := c.conn.ReadAsInt()
	if err != nil {
		return 0,err
	}
	if i == -2{
		return 0,RedisKeyNotExist
	}
	return i,nil
}
//Redis RANDOMKEY 命令从当前数据库中随机返回一个 key 。
func (c *Command) RandomKey() (string,error) {
	if c.conn == nil {
		return "",RedisConnError
	}

	_,err := c.conn.WriteString("RANDOMKEY\r\n")
	if err != nil {
		return "",err
	}
	s,err := c.conn.ReadAsString()

	return s,nil
}
//Redis Rename 命令用于修改 key 的名称 。
func (c *Command) Rename(oldKey,newKey string) (error) {
	if c.conn == nil {
		return RedisConnError
	}

	_,err := c.conn.WriteString(fmt.Sprintf("RENAME %s %s\r\n",oldKey,newKey))
	if err != nil {
		return err
	}
	s,err := c.conn.ReadAsString()

	if s == "OK" {
		return nil
	}else {
		return errors.New(s)
	}
	return err
}
//Redis Renamenx 命令用于在新的 key 不存在时修改 key 的名称 。
func (c *Command) RenameNx(oldKey,newKey string) (bool,error) {
	if c.conn == nil {
		return false,RedisConnError
	}

	_,err := c.conn.WriteString(fmt.Sprintf("RENAMENX %s %s\r\n",oldKey,newKey))
	if err != nil {
		return false,err
	}
	i,err := c.conn.ReadAsInt()
	if err != nil {
		return false,err
	}
	if i == 1 {
		return true,nil
	}
	return false,nil
}
//Redis Type 命令用于返回 key 所储存的值的类型。
func (c *Command) Type(key string) (int,error){
	if c.conn == nil {
		return 0,RedisConnError
	}

	_,err := c.conn.WriteString(fmt.Sprintf("TTL %s\r\n",key))
	if err != nil {
		return 0,err
	}
	s,err := c.conn.ReadAsString()
	if err != nil {
		return 0,err
	}
	if s == "string" {
		return REDIS_STRING,nil
	}
	if s == "list" {
		return REDIS_LIST,nil
	}
	if s == "set" {
		return REDIS_SET,nil
	}
	if s == "zset" {
		return REDIS_ZSET,nil
	}
	if s == "hash"{
		return REDIS_HASH,nil
	}
	return REDIS_NOT_FOUND,nil
}

















